﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using OptusMobile.Web.ServerComponents.DAL;
using OptusMobile.Web.ServerComponents.Common;

namespace OptusMobile.Web.ServerComponents.BAL.PlanManagement
{
    public class PlanManager : EFManagerBase
    {
        public List<V_CapDetail> ReadAllCapDetails()
        {
            try
            {
                return this.ObjectContext.V_CapDetailSet.ToList();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<V_CapDetail> ReadPlanCaps(string planID)
        {
            try
            {
                return this.ObjectContext.V_CapDetailSet.Where(cap=>cap.planID==planID).ToList();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<ServerComponents.DAL.Plan> ReadAllPlans()
        {
            try
            {
                return this.ObjectContext.PlanSet.ToList();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<ServerComponents.DAL.ExtraData> ReadAllDataPackages()
        {
            try
            {
                return this.ObjectContext.ExtraDataSet.ToList();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<ServerComponents.DAL.ExtraMessage> ReadAllMessagePackages()
        {
            try
            {
                return this.ObjectContext.ExtraMessageSet.ToList();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Calculates the actual monthly cost of a user
        /// </summary>
        /// <param name="currentPlan">The plan of the user's contract</param>
        /// <param name="historyAverage">The average usage of the user in the last six months</param>
        /// <param name="messagePackage">The message package on user's current contract</param>
        /// <param name="dataPackage">The data package on user's current contract</param>
        /// <returns>The user's actual monthly cost on current contract</returns>
        public decimal CalculateActualValue(OptusMobile.Web.ServerComponents.DAL.Plan currentPlan, CustomerUsageHistroy historyAverage, ExtraMessage messagePackage,ExtraData dataPackage)
        {
            decimal actualValue = currentPlan.monthlyFee;

            decimal? callToOptusValue = (currentPlan.flagCall * historyAverage.callsToOptus + currentPlan.callRate * (decimal)historyAverage.totalCallTimeToOptus) / 100;
            decimal? callToOtherValue = (currentPlan.flagCall * historyAverage.callsToOther + currentPlan.callRate * (decimal)historyAverage.totalCallTimeToOther) / 100;

            decimal? totalCallValue = callToOptusValue + callToOtherValue;
            decimal messageToOptusValue = currentPlan.perMessageFee * historyAverage.messageToOptus / 100;
            decimal messageToOtherValue = currentPlan.perMessageFee * historyAverage.messageToOther / 100;
            decimal totalMessageValue = messageToOptusValue + messageToOtherValue;
            decimal dataValue = (decimal)(historyAverage.data * 0.015 * 1024);
            decimal totalValue = totalCallValue.Value + totalMessageValue + dataValue;

            if ((currentPlan.monthlyFee == 19 || currentPlan.monthlyFee == 49))
            {
                // no message package
                if (messagePackage.exMessagePrice == 0)
                {
                    // calls and messages to optus exceed part
                    if (callToOptusValue + messageToOptusValue > currentPlan.callRateToOptus)
                    {
                        actualValue += callToOptusValue.Value + messageToOptusValue - currentPlan.callRateToOptus;
                    }

                    //calls and messages to others exceed part 
                    if (callToOtherValue + messageToOtherValue > currentPlan.callRateToOther)
                    {
                        actualValue += callToOtherValue.Value + messageToOtherValue - currentPlan.callRateToOther;
                    }
                }
                //Optus2Optus Unlimited SMS/MMS Pack package
                else if (messagePackage.exMessagePrice == 5)
                {
                    actualValue += 5;

                    // calls to optus exceed part
                    if (callToOptusValue > currentPlan.callRateToOptus)
                    {
                        actualValue += callToOptusValue.Value - currentPlan.callRateToOptus;
                    }

                    //calls and messages to others exceed part 
                    if (callToOtherValue + messageToOtherValue > currentPlan.callRateToOther)
                    {
                        actualValue += callToOtherValue.Value + messageToOtherValue - currentPlan.callRateToOther;
                    }
                }
                //Optus AnyOne 500 SMS/MMS Pack package
                else if (messagePackage.exMessagePrice == 10)
                {
                    actualValue += 10;

                    //actual messsages to others value
                    decimal actualMessageToOthersValue = 0;
                    if (historyAverage.messageToOther > 500)
                    {
                        actualMessageToOthersValue = (decimal)0.25 * (historyAverage.messageToOther - 500);
                    }

                    // calls and messages to optus exceed part
                    if (callToOptusValue + messageToOptusValue > currentPlan.callRateToOptus)
                    {
                        actualValue += callToOptusValue.Value + messageToOptusValue - currentPlan.callRateToOptus;
                    }

                    //calls and messages to others exceed part 
                    if (callToOtherValue + actualMessageToOthersValue > currentPlan.callRateToOther)
                    {
                        actualValue += callToOtherValue.Value + actualMessageToOthersValue - currentPlan.callRateToOther;
                    }
                }
                //Optus AnyOne Unlimited SMS/MMS package
                else if (messagePackage.exMessagePrice == 15)
                {
                    actualValue += 15;

                    // calls to optus exceed part
                    if (callToOptusValue > currentPlan.callRateToOptus)
                    {
                        actualValue += callToOptusValue.Value - currentPlan.callRateToOptus;
                    }
                    //calls to others exceed part 
                    if (callToOtherValue > currentPlan.callRateToOther)
                    {
                        actualValue += callToOtherValue.Value - currentPlan.callRateToOther;
                    }
                }
                else
                {
                    //leave for future packages
                }
            }
            else if ((currentPlan.monthlyFee == 59 || currentPlan.monthlyFee == 79))
            {
                // calls to optus exceed part
                if (callToOptusValue > currentPlan.callRateToOptus)
                {
                    actualValue += callToOptusValue.Value - currentPlan.callRateToOptus;
                }
                //calls to others exceed part 
                if (callToOtherValue > currentPlan.callRateToOther)
                {
                    actualValue += callToOtherValue.Value - currentPlan.callRateToOther;
                }
                actualValue += messagePackage.exMessagePrice;
            }
            else if (currentPlan.monthlyFee == 99)
            {
                actualValue += messagePackage.exMessagePrice;
            }
            else
            {
                //leave for future plans
            }

            //calcualtes data value
            if (dataPackage.exDataPrice == 0)
            {
                actualValue += dataValue;
            }
            else
            {
                actualValue += dataPackage.exDataPrice;

                //calculates the exceed data value
                if (historyAverage.data > dataPackage.exDataAmount)
                {
                    actualValue += (decimal)((historyAverage.data - dataPackage.exDataAmount) * 0.015 * 1024);
                }
            }
            return actualValue;
        }

        public decimal CalculateActualValue(OptusMobile.Web.ServerComponents.DAL.Plan currentPlan, CustomerUsageHistroy historyAverage, ExtraMessage messagePackage)
        {
            decimal actualValue = currentPlan.monthlyFee;

            decimal? callToOptusValue = (currentPlan.flagCall * historyAverage.callsToOptus + currentPlan.callRate * (decimal)historyAverage.totalCallTimeToOptus) / 100;
            decimal? callToOtherValue = (currentPlan.flagCall * historyAverage.callsToOther + currentPlan.callRate * (decimal)historyAverage.totalCallTimeToOther) / 100;

            decimal? totalCallValue = callToOptusValue + callToOtherValue;
            decimal messageToOptusValue = currentPlan.perMessageFee * historyAverage.messageToOptus / 100;
            decimal messageToOtherValue = currentPlan.perMessageFee * historyAverage.messageToOther / 100;
            decimal totalMessageValue = messageToOptusValue + messageToOtherValue;
            decimal dataValue = (decimal)(historyAverage.data * 0.015 * 1024);
            decimal totalValue = totalCallValue.Value + totalMessageValue + dataValue;

            if ((currentPlan.monthlyFee == 19 || currentPlan.monthlyFee == 49))
            {
                // no message package
                if (messagePackage.exMessagePrice == 0)
                {
                    // calls and messages to optus exceed part
                    if (callToOptusValue + messageToOptusValue > currentPlan.callRateToOptus)
                    {
                        actualValue += callToOptusValue.Value + messageToOptusValue - currentPlan.callRateToOptus;
                    }

                    //calls and messages to others exceed part 
                    if (callToOtherValue + messageToOtherValue > currentPlan.callRateToOther)
                    {
                        actualValue += callToOtherValue.Value + messageToOtherValue - currentPlan.callRateToOther;
                    }
                }
                //Optus2Optus Unlimited SMS/MMS Pack package
                else if (messagePackage.exMessagePrice == 5)
                {
                    actualValue += 5;

                    // calls to optus exceed part
                    if (callToOptusValue > currentPlan.callRateToOptus)
                    {
                        actualValue += callToOptusValue.Value - currentPlan.callRateToOptus;
                    }

                    //calls and messages to others exceed part 
                    if (callToOtherValue + messageToOtherValue > currentPlan.callRateToOther)
                    {
                        actualValue += callToOtherValue.Value + messageToOtherValue - currentPlan.callRateToOther;
                    }
                }
                //Optus AnyOne 500 SMS/MMS Pack package
                else if (messagePackage.exMessagePrice == 10)
                {
                    actualValue += 10;

                    //actual messsages to others value
                    decimal actualMessageToOthersValue = 0;
                    if (historyAverage.messageToOther > 500)
                    {
                        actualMessageToOthersValue = (decimal)0.25 * (historyAverage.messageToOther - 500);
                    }

                    // calls and messages to optus exceed part
                    if (callToOptusValue + messageToOptusValue > currentPlan.callRateToOptus)
                    {
                        actualValue += callToOptusValue.Value + messageToOptusValue - currentPlan.callRateToOptus;
                    }

                    //calls and messages to others exceed part 
                    if (callToOtherValue + actualMessageToOthersValue > currentPlan.callRateToOther)
                    {
                        actualValue += callToOtherValue.Value + actualMessageToOthersValue - currentPlan.callRateToOther;
                    }
                }
                //Optus AnyOne Unlimited SMS/MMS package
                else if (messagePackage.exMessagePrice == 15)
                {
                    actualValue += 15;

                    // calls to optus exceed part
                    if (callToOptusValue > currentPlan.callRateToOptus)
                    {
                        actualValue += callToOptusValue.Value - currentPlan.callRateToOptus;
                    }
                    //calls to others exceed part 
                    if (callToOtherValue > currentPlan.callRateToOther)
                    {
                        actualValue += callToOtherValue.Value - currentPlan.callRateToOther;
                    }
                }
                else
                {
                    //leave for future packages
                }
            }
            else if ((currentPlan.monthlyFee == 59 || currentPlan.monthlyFee == 79))
            {
                // calls to optus exceed part
                if (callToOptusValue > currentPlan.callRateToOptus)
                {
                    actualValue += callToOptusValue.Value - currentPlan.callRateToOptus;
                }
                //calls to others exceed part 
                if (callToOtherValue > currentPlan.callRateToOther)
                {
                    actualValue += callToOtherValue.Value - currentPlan.callRateToOther;
                }
                actualValue += messagePackage.exMessagePrice;
            }
            else if (currentPlan.monthlyFee == 99)
            {
                actualValue += messagePackage.exMessagePrice;
            }
            else
            {
                //leave for future plans
            }

            return actualValue;
        }

    }
}
